package com.weijian.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.weijian.common.result.ApiResponse;
import com.weijian.dal.entity.UploadBatch;
import com.weijian.dto.data.BatchStatistics;
import com.weijian.service.CsvDataService;
import com.weijian.service.FileStorageService;
import com.weijian.service.UploadBatchService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件上传接口
 */
@Slf4j
@Tag(name = "文件上传", description = "CSV文件上传与解析接口")
@RestController
@RequestMapping("/api/upload")
public class UploadController {

    @Autowired
    private CsvDataService csvDataService;

    @Autowired
    private UploadBatchService uploadBatchService;

    @Autowired
    private FileStorageService fileStorageService;

    /**
     * 创建新的批次（推荐方式）
     *
     * @param description 批次描述信息（可选）
     * @param governmentSubsidy 政府补贴（百分比）（可选）
     * @param timeValue 时间价值（百分比）（可选）
     * @return 批次信息，包含batchId
     */
    @Operation(summary = "创建新的批次")
    @PostMapping("/batch")
    public ApiResponse<Map<String, Object>> createBatch(
            @Parameter(description = "批次描述信息") @RequestParam(required = false) String description,
            @Parameter(description = "政府补贴（百分比）") @RequestParam(required = false) BigDecimal governmentSubsidy,
            @Parameter(description = "时间价值（百分比）") @RequestParam(required = false) BigDecimal timeValue) {

        // 验证至少提供一个参数（政府补贴或时间价值）
        if (governmentSubsidy == null && timeValue == null) {
            return ApiResponse.badRequest("政府补贴和时间价值不能同时为空，至少需要提供其中一个");
        }

        // 检查数据库中是否已存在相同的政府补贴和时间价值组合
        UploadBatch existingBatch;
        if (governmentSubsidy != null && timeValue != null) {
            // 两个字段都不为空，查找三个字段都匹配的记录
            existingBatch = uploadBatchService.lambdaQuery()
                    .eq(UploadBatch::getGovernmentSubsidy, governmentSubsidy)
                    .eq(UploadBatch::getTimeValue, timeValue)
                    .one();
        } else if (governmentSubsidy != null) {
            // 只有政府补贴不为空，查找政府补贴匹配且时间价值为null的记录
            existingBatch = uploadBatchService.lambdaQuery()
                    .eq(UploadBatch::getGovernmentSubsidy, governmentSubsidy)
                    .isNull(UploadBatch::getTimeValue)
                    .one();
        } else {
            // 只有时间价值不为空，查找时间价值匹配且政府补贴为null的记录
            existingBatch = uploadBatchService.lambdaQuery()
                    .eq(UploadBatch::getTimeValue, timeValue)
                    .isNull(UploadBatch::getGovernmentSubsidy)
                    .one();
        }

        if (existingBatch != null) {
            return ApiResponse.badRequest("已存在相同的政府补贴和时间价值组合，不能重复创建");
        }

        // 1. 生成批次ID
        Integer batchId = uploadBatchService.generateNewDataId();

        // 2. 创建批次记录
        UploadBatch uploadBatch = new UploadBatch();
        uploadBatch.setDataId(batchId);
        uploadBatch.setDescription(description);
        uploadBatch.setGovernmentSubsidy(governmentSubsidy);
        uploadBatch.setTimeValue(timeValue);
        boolean saved = uploadBatchService.save(uploadBatch);

        if (!saved) {
            return ApiResponse.badRequest("批次创建失败");
        }

        // 3. 返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("batchId", batchId);
        result.put("uploadBatch", uploadBatch);

        return ApiResponse.success(result);
    }

    /**
     * 更新批次元数据
     *
     * @param dataId 数据ID
     * @param description 批次描述信息
     * @param governmentSubsidy 政府补贴（百分比）
     * @param timeValue 时间价值（百分比）
     * @return 操作结果
     */
    @Operation(summary = "更新批次元数据")
    @PutMapping("/batch/metadata")
    public ApiResponse<String> updateBatchMetadata(
            @Parameter(description = "数据ID") @RequestParam Integer dataId,
            @Parameter(description = "批次描述信息") @RequestParam(required = false) String description,
            @Parameter(description = "政府补贴（百分比）") @RequestParam(required = false) BigDecimal governmentSubsidy,
            @Parameter(description = "时间价值（百分比）") @RequestParam(required = false) BigDecimal timeValue) {

        UploadBatch uploadBatch = uploadBatchService.getByDataId(dataId);
        if (uploadBatch == null) {
            return ApiResponse.badRequest("批次不存在");
        }

        uploadBatch.setDescription(description);
        uploadBatch.setGovernmentSubsidy(governmentSubsidy);
        uploadBatch.setTimeValue(timeValue);

        boolean result = uploadBatchService.saveOrUpdateBatch(uploadBatch);
        if (result) {
            return ApiResponse.success("批次元数据更新成功");
        } else {
            return ApiResponse.badRequest("批次元数据更新失败");
        }
    }

    /**
     * 获取批次元数据
     *
     * @param dataId 数据ID
     * @return 批次元数据
     */
    @Operation(summary = "获取批次元数据")
    @GetMapping("/batch/metadata")
    public ApiResponse<UploadBatch> getBatchMetadata(
            @Parameter(description = "数据ID") @RequestParam Integer dataId) {
        UploadBatch uploadBatch = uploadBatchService.getByDataId(dataId);
        if (uploadBatch != null) {
            return ApiResponse.success(uploadBatch);
        } else {
            return ApiResponse.badRequest("未找到指定的批次元数据");
        }
    }

    /**
     * 上传并解析路线CSV文件（改进版）
     *
     * @param file     路线CSV文件
     * @param batchId  批次ID（必填）
     * @return 解析结果
     */
    @Operation(summary = "上传并解析路线CSV文件")
    @PostMapping("/routes")
    public ApiResponse<Integer> uploadRouteCsv(
            @Parameter(description = "路线CSV文件") @RequestParam("file") MultipartFile file,
            @Parameter(description = "批次ID") @RequestParam("batchId") Integer batchId) {

        // 1. 校验批次是否存在
        UploadBatch uploadBatch = uploadBatchService.getByDataId(batchId);
        if (uploadBatch == null) {
            return ApiResponse.badRequest("批次不存在，请先创建批次");
        }

        // 2. 检查是否已上传过路线数据（业务层检查）
        if (csvDataService.isRouteDataExists(batchId)) {
            return ApiResponse.badRequest("该批次下已存在路线数据，不能重复上传");
        }

        try {
            // 3. 解析并保存到数据库
            ApiResponse<String> result = csvDataService.parseAndSaveRouteCsv(file, batchId);

            // 4. 保存原始文件到存储
            String filePath = fileStorageService.saveCsvFile(file, batchId, "route");
            log.info("路线文件已保存到: {}", filePath);

            // 5. 返回结果
            return ApiResponse.success(result.getMessage(), batchId);
        } catch (Exception e) {
            log.error("上传路线文件失败", e);
            return ApiResponse.internalError("上传失败: " + e.getMessage());
        }
    }

    /**
     * 上传并解析货物CSV文件（改进版）
     *
     * @param file     货物CSV文件
     * @param batchId  批次ID（必填）
     * @return 解析结果
     */
    @Operation(summary = "上传并解析货物CSV文件")
    @PostMapping("/shipments")
    public ApiResponse<Integer> uploadShipmentCsv(
            @Parameter(description = "货物CSV文件") @RequestParam("file") MultipartFile file,
            @Parameter(description = "批次ID") @RequestParam("batchId") Integer batchId) {

        // 1. 校验批次是否存在
        UploadBatch uploadBatch = uploadBatchService.getByDataId(batchId);
        if (uploadBatch == null) {
            return ApiResponse.badRequest("批次不存在，请先创建批次");
        }

        // 2. 检查是否已上传过货物数据（业务层检查）
        if (csvDataService.isShipmentDataExists(batchId)) {
            return ApiResponse.badRequest("该批次下已存在货物数据，不能重复上传");
        }

        try {
            // 3. 解析并保存到数据库
            ApiResponse<String> result = csvDataService.parseAndSaveShipmentCsv(file, batchId);

            // 4. 保存原始文件到存储
            String filePath = fileStorageService.saveCsvFile(file, batchId, "shipment");
            log.info("货物文件已保存到: {}", filePath);

            // 5. 返回结果
            return ApiResponse.success(result.getMessage(), batchId);
        } catch (Exception e) {
            log.error("上传货物文件失败", e);
            return ApiResponse.internalError("上传失败: " + e.getMessage());
        }
    }


    /**
     * 获取批次统计信息
     *
     * @param dataId 批次ID
     * @return 批次统计信息
     */
    @Operation(summary = "获取批次统计信息")
    @GetMapping("/batch/{dataId}/stats")
    public ApiResponse<BatchStatistics> getBatchStats(@PathVariable Integer dataId) {
        // 1. 检查批次是否存在
        UploadBatch uploadBatch = uploadBatchService.getByDataId(dataId);
        if (uploadBatch == null) {
            return ApiResponse.badRequest("批次不存在");
        }

        // 2. 获取统计数据（业务层）
        BatchStatistics statistics = csvDataService.getBatchStatistics(dataId);
        if (statistics == null) {
            return ApiResponse.badRequest("获取统计信息失败");
        }

        // 3. 构建响应
        return ApiResponse.success(statistics);
    }

    /**
     * 获取批次列表（分页）
     *
     * @param page 页码（从1开始）
     * @param size 每页大小
     * @return 批次列表
     */
    @Operation(summary = "获取批次列表")
    @GetMapping("/batch/list")
    public ApiResponse<Page<UploadBatch>> getBatchList(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size) {

        Page<UploadBatch> batchPage = uploadBatchService.page(
                new Page<>(page, size),
                Wrappers.emptyWrapper()
        );

        return ApiResponse.success(batchPage);
    }
}